
package com.hlkj.pay.app.merchant.ext.impl.helipay.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import cn.hutool.core.io.FileTypeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.impl.helipay.constant.HeliPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.HeliPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.OKHttpLogger;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.SignAndEncryptedContent;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.req.HeliPayAccessReq;
import com.hlkj.pay.app.merchant.ext.impl.helipay.dto.req.HeliPayAccessRes;
import com.hlkj.pay.app.merchant.ext.impl.helipay.util.HeliPaySignUtil;
import com.hlkj.pay.app.merchant.ext.impl.helipay.util.SignatureType;
import com.hlkj.pay.common.PayResultCode;
import com.hlkj.pay.common.constants.BaseConstants;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.SM2Utils;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.StringPool;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.time.StopWatch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 汇付 商户进件参数处理
 * 
 * @author HlpayTeam
 * @date 2024/09/26 12:02
 */
@Slf4j
@Service
public class HeliPayMerchantCommonParamsHandle<T> {

    @Autowired
    private OkHttpTemplate okHttpTemplate;

    @Value("${spring.profiles.active}")
    private String active;

    public static OkHttpClient client = new OkHttpClient.Builder().connectTimeout(50, TimeUnit.SECONDS).readTimeout(2, TimeUnit.MINUTES).addNetworkInterceptor(logInterceptor())
            .build();

    private static HttpLoggingInterceptor logInterceptor() {
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor(new OKHttpLogger());
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return logInterceptor;
    }

    /**
     * 进件请求
     * 
     * @param url
     * @param interfaceName
     * @param heliPayConfig
     * @param params
     * @param clazz
     * @return
     */
    public CommonResult<T> heliPayAccessRequest(String url, String interfaceName, HeliPayConfig heliPayConfig, String params, Class<T> clazz) {
        log.info("合利宝请求接口 interfaceName:{}, 请求参数:{}", interfaceName, params);
        try {
            SignAndEncryptedContent signAndEncryptedContent = HeliPaySignUtil.encryptAndSign(heliPayConfig, params);
            HeliPayAccessReq heliPayAccessReq = new HeliPayAccessReq();
            heliPayAccessReq.setInterfaceName(interfaceName);
            heliPayAccessReq.setSign(signAndEncryptedContent.getSign());
            heliPayAccessReq.setMerchantNo(heliPayConfig.getMerchantNo());
            heliPayAccessReq.setBody(signAndEncryptedContent.getEncryptedStr());
            heliPayAccessReq.setEncryptionKey(signAndEncryptedContent.getEncryptionKey());
            // log.info("合利宝返回参数 interfaceName:{}, 请求数据:{}", interfaceName,
            // JsonUtils.toJsonString(heliPayAccessReq));
            String post = postForm(url, interfaceName, signAndEncryptedContent.getEncryptedStr(), signAndEncryptedContent.getSign(), SignatureType.SM3WITHSM2,
                    signAndEncryptedContent.getEncryptionKey(), heliPayConfig.getMerchantNo(), null);
            // String post
            // ="{\"success\":true,\"code\":\"0000\",\"data\":\"x5I5CnSGv13NkC+7eVS/2DjJrahm0EbyiSVEJnBL2SdyKq6esJd5Ipbe9ODa+33zjgSsQO61+Xu9Vvc7Ebh5ItIzlM8Ulhv8Oho9/Fs5I2a5FAy2rvuYKAw5i+8qmkSNPWDZvoVUDTAK/+d91R+vlLeptEadSxIFC3dGuz2Vp5w=\",\"sign\":\"MEUCIQDWZdQjaZ1GK2UgDpYmbudKYMzGYeu4+0fLsxMjlHTM8QIgZfhrg7+89Nh4i0NpbLFipJyqX1XBSb2CWB+fMSDOatA=\",\"signType\":\"SM3WITHSM2\",\"hostname\":\"shelipay_trx23\",\"interfaceName\":\"register\",\"encryptionKey\":\"BEDE5aTRmguFDb62Y8HOrqQ+9n3XmHrkIF/nZxJ24owDY6JcDRw5M0uypE2WNgx+oHsNM0Lm8Ln7yKRCvasvwRt/qnZ+4YVLw2TJgOOqmMPps8WGPW5QzWXEo8dhT8gzUOW/3Eu6x7V/Z6biDbbFwiE=\",\"timestamp\":\"2024-12-29_09:20:26.931\"}";

            log.info("合利宝请求接口 interfaceName:{}, 返回参数:{}", interfaceName, post);
            HeliPayAccessRes heliPayAccessRes = JSON.parseObject(post, HeliPayAccessRes.class);
            /** 业务处理是否成功 **/
            if (!heliPayAccessRes.isSuccess()) {
                // throw new RuntimeException(heliPayAccessRes.getMessage());
                return CommonResult.error(1, heliPayAccessRes.getMessage());
            }
            /** 响应码为 0000 需进行验签操作 **/
            if (!HeliPayConstant.REQUEST_SUCCESS.equals(heliPayAccessRes.getCode())) {
                return CommonResult.error(1, heliPayAccessRes.getMessage());
            }
            String decrypted = HeliPaySignUtil.verificationAndDecrypt(heliPayConfig, heliPayAccessRes);
            return CommonResult.success(JSON.parseObject(decrypted, clazz));
        }
        catch (Exception e) {
            e.printStackTrace();
            return CommonResult.error(1, e.getMessage());
        }
    }

    /**
     * 支付请求
     *
     * @param url
     * @param heliPayConfig
     * @param signFieldMap
     * @param noSignFieldMap
     * @return
     */
    public CommonResult<String> heliPayAccountRequest(String url, HeliPayConfig heliPayConfig, Map<String, String> signFieldMap, Map<String, String> noSignFieldMap) {
        try {
            String joiner = HeliPaySignUtil.doSignStrAppend(signFieldMap);
            joiner = joiner + StringPool.AMPERSAND + heliPayConfig.getMd5Key();
            log.info("合利宝支付签名字符串 data:{}", joiner);
            // 使用商户的私钥进行签名
            String sign = HeliPaySignUtil.disguiseMD5(joiner.trim());
            signFieldMap.put("sign", sign);
            if (!CollectionUtils.isEmpty(noSignFieldMap)) {
                signFieldMap.putAll(noSignFieldMap);
            }
            log.info("合利宝支付最终请求参数 data:{}", JsonUtils.toJsonString(signFieldMap));
            String post = getHttpResp(signFieldMap, url);
            return CommonResult.success(post);
        }
        catch (Exception e) {
            return CommonResult.error(1, e.getMessage());
        }
    }

    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpg");

    private static final MediaType MEDIA_TYPE_VIDEO_MP4 = MediaType.parse("video/mp4");

    public String postForm(String url, String interfaceName, String encrypted, String sign, SignatureType signType, String encryptionKey, String merchantNo, File... files) {

        RequestBody requestBody = null;
        if (files == null || files.length == 0) {
            FormBody.Builder builder = new FormBody.Builder().add("interfaceName", interfaceName).add("body", encrypted).add("sign", sign).add("merchantNo", merchantNo);
            if (signType != null) {
                builder.add("signType", signType.name());
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(encryptionKey)) {
                builder.add("encryptionKey", encryptionKey);
            }
            requestBody = builder.build();
        }
        else if (files.length == 1) {
            File singleFile = files[0];
            String fileType = FileTypeUtil.getType(singleFile);
            RequestBody fileBody = RequestBody.create(MEDIA_TYPE_JPG, singleFile);
            if (StrUtil.equalsIgnoreCase("mp4", fileType)) {
                fileBody = RequestBody.create(MEDIA_TYPE_VIDEO_MP4, singleFile);
            }
            MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("interfaceName", interfaceName)
                    .addFormDataPart("body", encrypted).addFormDataPart("sign", sign).addFormDataPart("merchantNo", merchantNo)
                    .addFormDataPart("file", singleFile.getName(), fileBody);
            if (signType != null) {
                builder.addFormDataPart("signType", signType.name());
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(encryptionKey)) {
                builder.addFormDataPart("encryptionKey", encryptionKey);
            }
            requestBody = builder.build();
        }
        else {
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);
            builder.addFormDataPart("interfaceName", interfaceName);
            builder.addFormDataPart("body", encrypted);
            builder.addFormDataPart("sign", sign);
            builder.addFormDataPart("merchantNo", merchantNo);
            builder.addFormDataPart("authorizationForSettlement", "authorizationForSettlement", RequestBody.create(MEDIA_TYPE_JPG, files[0]));
            String[] fileNames = { "accountOpeningCertificate", "frontOfIdCard", "backOfIdCard", "handheldOfIdCard", "handheldOfBankCard", "subleaseCertificate", "bankCard" };
            for (int i = 1; i < files.length; i++) {
                File file = files[i];
                if (file.length() == 0) {
                    builder.addFormDataPart(fileNames[i - 1], "", RequestBody.create(MediaType.parse("application/octet-stream"), file));
                }
                else {
                    builder.addFormDataPart(fileNames[i - 1], file.getName(), RequestBody.create(MEDIA_TYPE_JPG, file));
                }
            }
            if (signType != null) {
                builder.addFormDataPart("signType", signType.name());
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(encryptionKey)) {
                builder.addFormDataPart("encryptionKey", encryptionKey);
            }
            requestBody = builder.build();
        }

        Request request = new Request.Builder() // okHttp post
                .url(url).post(requestBody).build();
        Response response = null;

        StopWatch watch = new StopWatch();
        watch.start();
        try {
            response = client.newCall(request).execute();
        }
        catch (IOException e) {
            log.error("postForm interfaceName:" + interfaceName, e);
            throw new RuntimeException("请求出错", e);
        }
        watch.split();
        log.info("处理时间：" + watch.getSplitTime() + "ms");
        watch.stop();

        if (!response.isSuccessful()) {
            try {
                log.info(response.body().string());
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("请求失败了: http response code: " + response.code());
        }
        ResponseBody body = response.body();
        String str = null;
        try {
            if (body == null) {
                throw new RuntimeException("响应 body 体为空");
            }
            str = body.string();
        }
        catch (Exception e) {
            throw new RuntimeException("处理响应消息过程中出错了", e);
        }
        log.info("url:" + url + ",返回的JSON串：" + str);
        return str;
    }

    /**
     * 支付产品请求
     * 
     * @param url
     * @param heliPayConfig
     * @param signFieldMap
     * @param noSignFieldMap
     * @return
     */
    public CommonResult<String> heliPayOrderRequest(String url, HeliPayConfig heliPayConfig, LinkedHashMap<String, String> signFieldMap, Map<String, String> noSignFieldMap) {
        try {
            String joiner = HeliPaySignUtil.doSignStrAppend(signFieldMap);
            log.info("合利宝支付签名字符串 data:{}", joiner);
            // 使用商户的私钥进行签名
            String privateKey = HeliPaySignUtil.getPrivateKeyStr(heliPayConfig.getPrivateKeyPath(), heliPayConfig.getSm2Key());
            String sign = SM2Utils.sign(joiner, privateKey);
            signFieldMap.put("sign", sign);
            signFieldMap.put("signatureType", "SM3WITHSM2");
            if (!CollectionUtils.isEmpty(noSignFieldMap)) {
                signFieldMap.putAll(noSignFieldMap);
            }
            log.info("合利宝支付最终请求参数 url:{},data:{}",url, JsonUtils.toJsonString(signFieldMap));
            String post = getHttpResp(signFieldMap, url);
            return CommonResult.success(post);
        }
        catch (Exception e) {
            return CommonResult.error(1, e.getMessage());
        }
    }

    /**
     * 公共产品请求
     *
     * @param url
     * @param heliPayConfig
     * @param signFieldMap
     * @param noSignFieldMap
     * @return
     */
    public CommonResult<String> heliPayCommonRequest(String url, HeliPayConfig heliPayConfig, LinkedHashMap<String, String> signFieldMap, Map<String, String> noSignFieldMap) {
        try {
            signFieldMap.put("signType", "SM3WITHSM2");
            String joiner = HeliPaySignUtil.doSignStrAppend(signFieldMap);
            log.info("合利宝公共产品签名字符串 data:{}", joiner);
            // 使用商户的私钥进行签名
            String privateKey = HeliPaySignUtil.getPrivateKeyStr(heliPayConfig.getPrivateKeyPath(), heliPayConfig.getSm2Key());
            String sign = SM2Utils.sign(joiner, privateKey);
            signFieldMap.put("sign", sign);
            if (!CollectionUtils.isEmpty(noSignFieldMap)) {
                signFieldMap.putAll(noSignFieldMap);
            }
            log.info("合利宝公共产品最终请求参数 url:{},data:{}",url, JsonUtils.toJsonString(signFieldMap));
            String post = getHttpResp(signFieldMap, url);
            if(StringUtils.hasText(post)){
                return CommonResult.success(post);
            }else {
                return CommonResult.error(1,"合利宝接口请求失败,返回内容为空");
            }
        }
        catch (Exception e) {
            return CommonResult.error(1, e.getMessage());
        }
    }

    public static String getHttpResp(Map<String, String> reqMap, String httpUrl) {
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(httpUrl);
        method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
        method.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, new Integer(300000));
        String response = "";

        // Map<String, Object> mp = new HashMap<String, Object>();
        try {
            NameValuePair[] nvps = getNameValuePair(reqMap);
            method.setRequestBody(nvps);
            int rescode = client.executeMethod(method);
            // mp.put("statusCode", rescode);

            // log.info("url:" + httpUrl + " ,http rescode:" + rescode);
            // if (rescode == HttpStatus.SC_OK) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
            String curline = "";
            while ((curline = reader.readLine()) != null) {
                response += curline;
            }
            log.info("http response:" + response);
            // mp.put("response", response);
            return response;
            // }
        }
        catch (Exception e) {
            log.error("http request error,url:" + httpUrl, e);
        }
        finally {
            method.releaseConnection();
        }
        return "{}";
    }

    public static NameValuePair[] getNameValuePair(Map<String, String> bean) {
        List<NameValuePair> x = new ArrayList<NameValuePair>();
        for (Iterator<String> iterator = bean.keySet().iterator(); iterator.hasNext();) {
            String type = (String) iterator.next();
            x.add(new NameValuePair(type, String.valueOf(bean.get(type))));
        }
        Object[] y = x.toArray();
        NameValuePair[] n = new NameValuePair[y.length];
        System.arraycopy(y, 0, n, 0, y.length);
        return n;
    }

    public CommonResult<HeliPayConfig> heliPayConfig(ProviderChannelConfigDO providerChannelConfigDO, boolean test) {
        String paramsConfig = providerChannelConfigDO.getParamsConfig();
        if (StringUtils.isEmpty(paramsConfig)) {
            return CommonResult.error(PayResultCode.PAY_CHANNEL_CONFIG_NOT_EXITS);
        }
        // 配置转换
        HeliPayConfig heliPayConfig = null;
        try {

            heliPayConfig = JsonUtils.parseObject(paramsConfig, HeliPayConfig.class);
            if (!active.equals("prod")) {
                log.info("合利宝非prod 环境,更新证书信息");
                heliPayConfig
                        .setPlatPublicKeyPath(heliPayConfig.getPlatPublicKeyPath().replace("/www/wwwroot/pay/uploads/secret/20241231/", "D:/文档/合利宝/20241227/"));
                heliPayConfig.setPrivateKeyPath(heliPayConfig.getPrivateKeyPath().replace("/www/wwwroot/pay/uploads/secret/20241231/", "D:/文档/合利宝/20241227/"));
                heliPayConfig.setPublicKeyPath(heliPayConfig.getPublicKeyPath().replace("/www/wwwroot/pay/uploads/secret/20241231/", "D:/文档/合利宝/20241227/"));
            }
            return CommonResult.success(heliPayConfig);
        }
        catch (Exception e) {
            String format = String.format(PayResultCode.PAY_CHANNEL_CONFIG_ERROR.getMsg(), "合利宝");
            return CommonResult.error(PayResultCode.PAY_CHANNEL_CONFIG_NOT_EXITS.getCode(), format);
        }
    }

    public static String date(String date) {
        if (!StringUtils.hasText(date)) {
            return null;
        }
        if(BaseConstants.MAX_DATA_STRING.equals(date)){
            return "长期有效";
        }
        return date.replace("-", "");
    }

    public static String licenseType(String code) {
        if (!StringUtils.hasText(code)) {
            return null;
        }
        // 营业执照类型：
        // 1：营业执照
        // 2：营业执照(多证合一)
        // 3：事业单位法人证书
        // 4：社会团体法人登记证书
        // 5：民办非企业单位登记证书
        // 6：基金会法人登记证书
        // 7：宗教活动场所登记证
        // 8：其他证书/批文/证明
        // 9：执业许可证/执业证
        // 10：基层群众性自治组织特别法人统一社会信用代码证
        // 11：农村集体经济组织登记证
        // 12：业主委员会备案证明

        // CERTIFICATE_TYPE_2388 事业单位法人证书
        // CERTIFICATE_TYPE_2389 统一社会信用代码证书
        // CERTIFICATE_TYPE_2390 有偿服务许可证（军队医院适用）
        // CERTIFICATE_TYPE_2391 医疗机构执业许可证（军队医院适用）
        // CERTIFICATE_TYPE_2392 企业营业执照（挂靠企业的党组织适用）
        // CERTIFICATE_TYPE_2393 组织机构代码证（政府机关适用）
        // CERTIFICATE_TYPE_2394 社会团体法人登记证书
        // CERTIFICATE_TYPE_2395 民办非企业单位登记证书
        // CERTIFICATE_TYPE_2396 基金会法人登记证书
        // CERTIFICATE_TYPE_2397 慈善组织公开募捐资格证书
        // CERTIFICATE_TYPE_2398 农民专业合作社法人营业执照
        // CERTIFICATE_TYPE_2399 宗教活动场所登记证
        // CERTIFICATE_TYPE_2400 其他证书/批文/证明
        switch (code) {
            case "1":
            case "2":
            case "10":
                return "CERTIFICATE_TYPE_2389";
            case "3":
                return "CERTIFICATE_TYPE_2388";
            case "4":
                return "CERTIFICATE_TYPE_2394";
            case "5":
                return "CERTIFICATE_TYPE_2395";
            case "6":
                return "CERTIFICATE_TYPE_2396";
            case "7":
                return "CERTIFICATE_TYPE_2399";
            case "8":
            case "9":
            case "12":
                return "CERTIFICATE_TYPE_2400";
            case "11":
                return "CERTIFICATE_TYPE_2398";
            default:
                return null;
        }
    }

    public static String certType(String code) {
        if (!StringUtils.hasText(code)) {
            return null;
        }
        // 营业执照类型：
        // 1:身份证
        // 2:护照
        // 3:军官证
        // 4:士兵证
        // 5:回乡证
        // 6:户口本
        // 7:外国护照
        // 8:其他
        // 9:暂住证
        // 10:警官证
        // 11:文职干部证
        // 12:港澳台同胞通行证
        // 13:外国人居留证
        // 14:台胞证
        // 15:港澳台居住证
        // 16：营业执照 （只有部分场景才会用到 如 受益人和股东）

        // IDCARD 身份证
        // PASSPORT 护照
        // SOLDIERSCERTIFICATE 士兵证
        // OFFICERSCERTIFICATE 军官证
        // GATXCERTIFICATE 香港居民来往内地通行证
        // TWNDCERTIFICATE 台湾同胞来往内地通行证
        // MACAOCERTIFICATE 澳门来往内地通行证
        switch (code) {
            case "1":
                return "IDCARD";
            case "2":
                return "PASSPORT";
            case "3":
                return "OFFICERSCERTIFICATE";
            case "4":
                return "SOLDIERSCERTIFICATE";
            case "14":
                return "TWNDCERTIFICATE";
            default:
                return null;
        }
    }

    public static String payUrl(boolean test) {
        // 测试环境：https://test.wsmsd.cn/sit/api/v2/mms/openApi/wechatParamConf
        // 生产环境：https://s2.lakala.com/api/v2/mms/openApi/wechatParamConf
        if (test) {
            return "https://test.trx.helipay.com/trx/app/interface.action";
        }
        else {
            return "https://pay.trx.helipay.com/trx/app/interface.action";
        }
    }

    public static String accessUrl(boolean test) {
        // 测试环境: https://test.wsmsd.cn/sit/htkregistration/merchant (POST)
        // ⽣产环境: https://htkactvi.lakala.com/registration/merchant (POST)
        if (test) {
            return HeliPayConstant.MERCHANT_DOMAIN_TEST;
        }
        else {
            return HeliPayConstant.MERCHANT_DOMAIN_PROD;
        }
    }

    public static String accessAccountUrl(boolean test) {
        // 测试环境: https://test.wsmsd.cn/sit/htkregistration/merchant (POST)
        // ⽣产环境: https://htkactvi.lakala.com/registration/merchant (POST)
        if (test) {
            return "http://test.trx.helipay.com/trx/merchant/interface.action";
        }
        else {
            return "http://pay.trx.helipay.com/trx/merchant/interface.action";
        }
    }
    public static String settleAccountUrl(boolean test) {
        // 测试环境: https://test.wsmsd.cn/sit/htkregistration/merchant (POST)
        // ⽣产环境: https://htkactvi.lakala.com/registration/merchant (POST)
        if (test) {
            return "http://test.trx.helipay.com/trx/transfer/interface.action";
        }
        else {
            return "http://transfer.trx.helipay.com/trx/transfer/interface.action";
        }
    }

    public static void main(String[] args) throws Exception {
        String url = "http://entry.trx.helipay.com/trx/merchantEntry/interface.action";
        String interfaceName = "wxPublicApplyQuery";

        HeliPayConfig heliPayConfig = new HeliPayConfig();
        heliPayConfig.setMerchantNo("C1808766114");
        heliPayConfig.setPlatPublicKeyPath("D:/文档/合利宝/C1808766114/helipayPublicKey.cer");
        heliPayConfig.setPrivateKeyPath("D:/文档/合利宝/C1808766114/C1808766114_2409030226587071_privateKey.pfx");
        heliPayConfig.setPublicKeyPath("D:/文档/合利宝/C1808766114/C1808766114_2409030226587071_publicKey.cer");
        heliPayConfig.setSm2Key("123456");

        Map<String, String> params = new HashMap<>();
        params.put("merchantNo", "E1808824035");
        params.put("orderNo", System.currentTimeMillis() + "");
        SignAndEncryptedContent signAndEncryptedContent = HeliPaySignUtil.encryptAndSign(heliPayConfig, JsonUtils.toJsonString(params));
        FormBody.Builder builder = new FormBody.Builder().add("interfaceName", interfaceName).add("body", signAndEncryptedContent.getEncryptedStr()).
                add("sign", signAndEncryptedContent.getSign()).add("merchantNo", heliPayConfig.getMerchantNo());
        builder.add("signType", "SM3WITHSM2");
        builder.add("encryptionKey", signAndEncryptedContent.getEncryptionKey());
        RequestBody requestBody = builder.build();
        Request request = new Request.Builder().url(url).post(requestBody).build();
        Response response = null;

        StopWatch watch = new StopWatch();
        watch.start();
        try {
            response = client.newCall(request).execute();
        }
        catch (IOException e) {
            log.error("postForm interfaceName:" + interfaceName, e);
            throw new RuntimeException("请求出错", e);
        }
        watch.split();
        log.info("处理时间：" + watch.getSplitTime() + "ms");
        watch.stop();

        if (!response.isSuccessful()) {
            try {
                log.info(response.body().string());
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            throw new RuntimeException("请求失败了: http response code: " + response.code());
        }
        ResponseBody body = response.body();
        String str = null;
        try {
            if (body == null) {
                throw new RuntimeException("响应 body 体为空");
            }
            str = body.string();
        }
        catch (Exception e) {
            throw new RuntimeException("处理响应消息过程中出错了", e);
        }
        log.info("url:" + url + ",返回的JSON串：" + str);
        HeliPayAccessRes heliPayAccessRes = JSON.parseObject(str, HeliPayAccessRes.class);
        String decrypted = HeliPaySignUtil.verificationAndDecrypt(heliPayConfig, heliPayAccessRes);
        System.out.println(decrypted);
    }

}
